import { cloneDeep } from "lodash";
import { initChess } from "../Chessman";
import { initBoardChessman } from "../config";
let flag = false;
export function stateReducer(state, action) {
  // if (flag) {
  //   console.warn(new Error("重复渲染"));
  //   return state;
  // }
  flag = true;
  const copyState = cloneDeep(state);
  switch (action.type) {
    case "move": {
      // 记录缓存
      const cacheLen = copyState.cache.length;
      // copyState.cache[copyState.cache.length - 1].checked(false);
      for (let i = 0; i < copyState.movePositionPaths.length; i++) {
        const [x, y] = copyState.movePositionPaths[i];
        if (x === action.moveX && y === action.moveY) {
          if (copyState.cache.length === cacheLen) {
            copyState.cache = [...copyState.cache, state.survivalChessman];
          }
          // 检测移动后是否被将军
          const canMove = copyState.checkedChessman.move(
            x,
            y,
            copyState.checkedChessman,
            copyState.survivalChessman
          );
          if (!canMove) return state;
          for (const [key, chessman] of copyState.survivalChessman) {
            if (
              chessman.x === x &&
              chessman.y === y &&
              chessman.camp !== state.checkedChessman.camp
            ) {
              // 清除已击杀的棋子
              copyState.survivalChessman.delete(chessman.key);
              break;
            }
          }
          // 清空预测路线
          initPredictionPath();
          // 取消选中棋子
          copyState.survivalChessman
            .get(state.checkedChessman.key)
            .checked(false);
          state.survivalChessman.get(state.checkedChessman.key).checked(false);
          copyState.checkedChessman = null;
          // 变更出手方
          copyState.round = state.round === "red" ? "black" : "red";

          flag = false;
        }
      }
      // 移动
      return copyState;
    }
    case "backMove":
      // 悔棋
      // 清空预测路线
      initPredictionPath();
      copyState.checkedChessman = null;
      copyState.survivalChessman = copyState.cache.pop();
      copyState.round = copyState.round === "red" ? "black" : "red";
      flag = false;
      return copyState;
    case "checked": {
      const board = document
        .querySelector(".chess-board")
        .querySelector(".prediction-drop");
      // 清空预测路线
      initPredictionPath();
      const key = action.key;
      if (state.checkedChessman) {
        // 已有选中的棋子 取消选中
        copyState.checkedChessman.checked(false);
        copyState.checkedChessman = null;
        if (key === state.checkedChessman.key) {
          // 清空路径
          copyState.movePositionPaths = [];
          return copyState;
        }
      }

      const { path: predictionMove } = copyState.survivalChessman
        .get(action.key)
        .predictionMove(copyState.survivalChessman);
      for (let i = 0; i < predictionMove.length; i++) {
        const [x, y] = predictionMove[i];
        const className = `prediction-drop-item x-${x} y-${y}`;
        board.getElementsByClassName(className)[0].classList.add("show");
      }

      copyState.survivalChessman.get(action.key).checked(true);
      copyState.checkedChessman = copyState.survivalChessman.get(action.key);
      copyState.movePositionPaths = predictionMove;
      flag = false;
      return copyState;
    }
    case "win":
      flag = false;
      copyState.winner = action.camp;
      return copyState;
    case "init": {
      const survivalChessman = new Map(
        initBoardChessman.map((item) => [item.key, item])
      );
      initChess(survivalChessman);

      const it1 = survivalChessman.values();
      let csm = null;
      do {
        csm = it1.next().value;
        if (!csm) continue;
        csm.setGetWinner((camp) => {
          return action.dispatch({ type: "win", camp });
        });
      } while (csm);

      copyState.survivalChessman = survivalChessman;
      copyState.round = "red";
      flag = false;
      return copyState;
    }
    default:
      alert("未记录的操作");
      flag = false;
      return copyState;
  }
}

function initPredictionPath() {
  const board = document
    .querySelector(".chess-board")
    .querySelector(".prediction-drop");
  for (let j = 0; j < board.children.length; j++) {
    const ele = board.children[j];
    ele.classList.remove("show");
  }
}
